package com.redepronik.negosys.seguridad.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Service;

import com.redepronik.negosys.rrhh.entity.Persona;
import com.redepronik.negosys.seguridad.dao.UsuarioDao;
import com.redepronik.negosys.seguridad.entity.Rol;
import com.redepronik.negosys.seguridad.entity.Rolusuario;
import com.redepronik.negosys.seguridad.entity.Usuario;

@Service
public class UsuarioServiceImpl implements UsuarioService, Serializable {

	private static final long serialVersionUID = 1L;

	@Autowired
	private UsuarioDao usuarioDao;

	@Autowired
	private RolService rolService;

	public String actualizar(Usuario usuario) {
		if (!usuarioDao.comprobarIndices(Usuario.class, "nombre",
				usuario.getNombre(), String.valueOf(usuario.getUsuarioid()))) {
			if (!usuarioDao.comprobarIndices(Usuario.class, "login",
					usuario.getLogin(), String.valueOf(usuario.getUsuarioid()))) {
				usuarioDao.actualizar(usuario);
				return "SAVE";
			} else
				return "EL LOGIN YA EXISTE";
		} else
			return "EL NOMBRE YA EXISTE";
	}

	public boolean compararClave(String clave1, String clave2) {
		if (clave1.compareTo(clave2) == 0)
			return true;
		else
			return false;
	}

	public void eliminar(Usuario usuario) {
		if (usuario.getEnabled())
			usuario.setEnabled(false);
		else
			usuario.setEnabled(true);
		usuarioDao.actualizar(usuario);
	}

	public String generarClave(String clave) {
		ShaPasswordEncoder shaPasswordEncoder = new ShaPasswordEncoder(256);
		return shaPasswordEncoder.encodePassword(clave, null);
	}

	public String insertar(Usuario usuario) {
		if (!usuarioDao.comprobarIndices(Usuario.class, "nombre",
				usuario.getNombre(), String.valueOf(usuario.getUsuarioid()))) {
			if (!usuarioDao.comprobarIndices(Usuario.class, "login",
					usuario.getLogin(), String.valueOf(usuario.getUsuarioid()))) {
				usuarioDao.insertar(usuario);
				return "SAVE";
			} else
				return "EL LOGIN YA EXISTE";
		} else
			return "EL NOMBRE YA EXISTE";
	}

	public String insertarRoles(Persona persona, List<String> roles) {
		Usuario usuario = persona.getUsuario();
		if (usuario == null) {
			usuario = new Usuario();
			usuario.setPersona(persona);
			usuario.setNombre(persona.getApellido() + " " + persona.getNombre());
			usuario.setLogin(persona.getCedula());
			usuario.setPassword(generarClave(persona.getCedula()));
			usuario.setEnabled(true);

			usuario.setRolusuarios(new ArrayList<Rolusuario>());
			for (String r : roles) {
				Rolusuario rolUsuario = new Rolusuario();
				Rol rol = rolService.obtenerPorNombre(r);
				rolUsuario.setRol(rol);
				rolUsuario.setActivo(true);
				usuario.addRolusuario(rolUsuario);
			}
			usuarioDao.insertar(usuario);
		} else {
			if (usuario.getRolusuarios() == null)
				usuario.setRolusuarios(new ArrayList<Rolusuario>());

			for (String r : roles) {
				Rolusuario rolUsuario = new Rolusuario();
				Rol rol = rolService.obtenerPorNombre(r);
				rolUsuario.setRol(rol);
				rolUsuario.setActivo(true);
				usuario.addRolusuario(rolUsuario);
			}
			usuarioDao.actualizar(usuario);
		}
		return "SAVE";
	}

	public List<Usuario> obtener() {
		List<Usuario> list = usuarioDao.obtenerPorHql(
				"select distinct u from Usuario u left join fetch u.rolusuarios "
						+ "order by u.nombre", new Object[] {});
		return list;
	}

	public Usuario obtenerPorLogin(String login) {
		Usuario usuario = usuarioDao.obtenerPorHql(
				"select distinct u from Usuario u left join fetch u.rolusuarios "
						+ "where u.login=?1", new Object[] { login }).get(0);
		return usuario;
	}

	public List<Usuario> obtenerPorLoginOrNombre(String criterio) {
		return usuarioDao
				.obtenerPorHql(
						"select u from Usuario u where u.login like ?1 or u.nombre like ?1 order by u.nombre",
						new Object[] { "%" + criterio + "%" });
	}

	public Usuario obtenerPorLoginSimple(String login) {
		// return usuarioDao.obtenerPorAtributo(Usuario.class, "login", login,
		// null);
		List<Usuario> listaUsuario = usuarioDao.obtenerPorHql(
				"select u from Usuario u where u.login=?1",
				new Object[] { login });

		if (!listaUsuario.isEmpty())
			return listaUsuario.get(0);
		else
			return null;
	}

	public List<Usuario> obtenerTodosPorBusqueda(String criterioBusquedaUsuario) {
		List<Usuario> lista = null;
		if (criterioBusquedaUsuario.compareToIgnoreCase("") != 0)
			lista = usuarioDao.obtenerPorHql(
					"select distinct u from Usuario u "
							+ "left join fetch u.rolusuarios ru "
							+ "left join fetch ru.rol r "
							+ "where u.login like ?1 or u.nombre like ?1 "
							+ "order by u.nombre", new Object[] { "%"
							+ criterioBusquedaUsuario + "%" });
		return lista;
	}

}